// 引入所需的模块
const multer = require('multer'); // 用于处理文件上传
const express = require('express'); // Express框架
const path = require('path'); // 处理文件和目录路径
const fs = require('fs-extra'); // 扩展的文件系统模块
const walkDir = require('klaw-sync'); // 递归遍历目录
const compressing = require('compressing'); // 用于压缩和解压缩文件
const router = express.Router(); // 创建一个新的路由器实例

// 引入自定义的工具函数
const { getFileHash, textCoding } = require('../handy'); 
const { getFileId } = require('../ai/common');
const { getImageManifest, writeImageManifest } = require('../manifest'); 
const upload = multer({ storage: multer.memoryStorage() });

// 处理上传ZIP文件的路由
router.post('/upload-zip', upload.single('file'), async (req, res) => {
    const zipFile = req.file;
    let originalName = textCoding(zipFile.originalname);
    const uuid = req.body.uuid; 
    const userUploadRootDir = path.join(global.__rootDir, 'uploads', uuid);
    await fs.mkdirp(userUploadRootDir);
    const zipFilePath = path.join(userUploadRootDir, originalName); 

    // 写入ZIP文件
    fs.writeFileSync(zipFilePath, zipFile.buffer); // 将文件缓冲区写入指定路径

    // 解压文件
    const hash = await getFileHash(zipFilePath); // 获取ZIP文件的哈希值
    const unzipFileDir = path.join(userUploadRootDir, hash);
    const tempUnzipDir = path.join(unzipFileDir, 'temp');
    const manifestFilePath = path.join(unzipFileDir, 'manifest.json');

    // 检查清单文件是否已存在
    if (fs.existsSync(manifestFilePath)) {
        const manifestJson = fs.readFileSync(manifestFilePath); // 读取清单文件
        res.json({
            code: 200,
            message: `文件上传成功，文件哈希值：${hash}`,
            hash: hash,
            fileList: JSON.parse(manifestJson).map(file => ({
              ...file,
              filePath: path.join(userUploadRootDir, file.hash, file.fileName) 
            })),
        });
        return;
    }

    await fs.mkdirp(tempUnzipDir);
    await compressing.zip.uncompress(zipFilePath, tempUnzipDir, {
        zipFileNameEncoding: 'gbk',
    });

    // 将所有解压的文件移动到根目录
    let fileList = walkDir(tempUnzipDir, { nodir: true }); // 遍历解压目录
    for (const pathItem of fileList) {
        const sourcePath = pathItem.path; // 源文件路径
        const fileName = path.basename(pathItem.path);
        const targetPath = path.join(unzipFileDir, fileName);
        fs.moveSync(sourcePath, targetPath, { overwrite: true });
    }

    // 删除临时解压目录
    fs.removeSync(tempUnzipDir);

    // 生成文件列表以返回给前端
    const sourceFiles = fs.readdirSync(unzipFileDir); // 读取解压目录中的文件
    fileList = [];
    for (const itemName of sourceFiles) {
        let itemPath = path.join(unzipFileDir, itemName); 
        const state = fs.statSync(itemPath);
        if (state.isDirectory()) continue;
        const itemExt = path.extname(itemPath);
        if (itemExt === '.json') continue;

        const fileHash = await getFileHash(itemPath);
        const fileName = path.basename(itemPath);
        fileList.push({
            fileName,
            hash: fileHash,
            filePath: path.join(userUploadRootDir, hash, fileName)
        });
    }

    // 如果文件列表不为空，写入清单文件
    if (fileList.length) {
        fs.writeFileSync(manifestFilePath, JSON.stringify(fileList, null, 4)); // 写入清单文件
    }

    res.json({
        code: 200,
        message: `文件上传成功，文件哈希值：${hash}`,
        hash: hash,
        fileList: fileList
    });
});

// 处理上传图像的路由
router.post('/upload-images', upload.array('images'), async (req, res) => {
    const uuid = req.body.uuid; // 获取UUID
    if (!uuid) {
        res.json({ code: 400, message: 'uuid不能为空' }); // 检查UUID是否存在
        return;
    }
    const zipFileHash = req.body.zipFileHash; // 获取ZIP文件哈希
    if (!zipFileHash) {
        res.json({ code: 400, message: 'zipFileHash不能为空' }); // 检查ZIP文件哈希是否存在
        return;
    }
    const pdfFileName = req.body.fileName; // 获取PDF文件名
    if (!pdfFileName) {
        res.json({ code: 400, message: 'fileName不能为空' }); // 检查文件名是否存在
        return;
    }
    const pdfFileHash = req.body.fileHash; // 获取PDF文件哈希
    if (!pdfFileHash) {
        res.json({ code: 400, message: 'fileHash不能为空' }); // 检查文件哈希是否存在
        return;
    }
    const images = req.files; // 获取上传的图像文件
    if (!Array.isArray(images) || images.length === 0) {
        res.json({ code: 400, message: '图片不能为空' }); // 检查图像文件是否存在
        return;
    }

    const uploadRootDir = path.join(global.__rootDir, 'uploads', uuid); // 用户上传根目录
    const zipUploadPath = path.join(uploadRootDir, zipFileHash); // ZIP文件上传路径
    const pdfUploadPath = path.join(zipUploadPath, pdfFileHash); // PDF文件上传路径
    await fs.mkdirp(pdfUploadPath); // 创建PDF文件上传目录
    let imageList = []; // 存储图像信息的列表
    let manifest = getImageManifest({ zipFileHash, pdfFileHash, uuid }); // 获取图像清单

    // 处理每个上传的图像
    for (const image of images) {
        const imageName = textCoding(image.originalname); // 对图像名称进行编码
        let imageInfo = manifest.imageList.find(
            (e) => e.imageName === imageName // 查找图像信息
        );
        if (!imageInfo) {
            imageInfo = {}; // 如果没有找到，创建新的图像信息对象
            manifest.imageList.push(imageInfo); // 将其添加到清单中
        }
        imageInfo.zipFileHash = zipFileHash; // 设置ZIP文件哈希
        imageInfo.pdfFileHash = pdfFileHash; // 设置PDF文件哈希
        imageInfo.imageName = imageName; // 设置图像名称
        const imageFilePath = path.join(pdfUploadPath, imageName); // 图像文件路径
        if (!fs.existsSync(imageFilePath)) {
            const imageBuffer = image.buffer; // 获取图像缓冲区
            fs.writeFileSync(imageFilePath, imageBuffer); // 写入图像文件
        }
        if (!imageInfo.fileId) {
            const fileId = await getFileId(imageFilePath); // 获取文件ID
            imageInfo.fileId = fileId; // 设置文件ID
        }
        imageList.push(imageInfo); // 将图像信息添加到列表中
    }

    writeImageManifest({ zipFileHash, pdfFileHash, uuid, manifest }); // 写入图像清单
    res.json({ code: 200, message: '上传成功', imageList: imageList }); // 返回上传成功的响应
});

// 导出路由
module.exports = router;